package com.zkyc.framework.common.aop;

import com.zkyc.framework.common.mapper.TimingMapper;
import com.zkyc.framework.common.pojo.SystemTiming;
import com.zkyc.framework.common.pool.TimingPoolFactory;
import com.zkyc.framework.common.pool.TimingSaveThread;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author bing.bai
 * @create 2022/6/1
 */
@Aspect
@Component
@Slf4j
public class TimingAspect {

    @Autowired
    private TimingMapper timingMapper;

    @Pointcut("@annotation(com.zkyc.framework.common.annotation.Timing)")
    public void TimingAop() {
    }


    @Around("TimingAop()")
    public Object timingSave(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String methodName = joinPoint.getSignature().getName();
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        long costTime = end - start;
        SystemTiming systemTiming = new SystemTiming();
        systemTiming.setCostTime(Integer.valueOf(costTime + ""));
        systemTiming.setMethodName(methodName);
        systemTiming.setRequestDate(new Date());
        if (sra != null) {
            HttpServletRequest request = sra.getRequest();
            if (request != null) {
                String websiteId = request.getHeader("websiteId");
                systemTiming.setWebsiteId(websiteId);
            }
        }
        /**
         * 线程池插入返回时间，不影响主流程
         */
        TimingPoolFactory.timingPool.execute(new TimingSaveThread(systemTiming, timingMapper));
        return result;
    }
}
